package thoven.achievement.net.jsonutil.service

import com.jayway.jsonpath.JsonPath
import com.jayway.jsonpath.PathNotFoundException
import com.google.gson.GsonBuilder

/**
 * JSONPath 查询服务
 */
object JsonPathQuery {
    
    private val prettyGson = GsonBuilder()
        .setPrettyPrinting()
        .serializeNulls()
        .disableHtmlEscaping()
        .create()
    
    /**
     * 执行 JSONPath 查询
     * @param json JSON 字符串
     * @param jsonPath JSONPath 表达式，例如: $.store.book[0].title
     * @return 查询结果（格式化的 JSON）
     */
    fun query(json: String, jsonPath: String): Result<String> {
        return try {
            val result = JsonPath.read<Any>(json, jsonPath)
            
            val formatted = when (result) {
                is String -> result
                is Number -> result.toString()
                is Boolean -> result.toString()
                null -> "null"
                else -> prettyGson.toJson(result)
            }
            
            Result.success(formatted)
        } catch (e: PathNotFoundException) {
            Result.failure(IllegalArgumentException("JSONPath not found: ${e.message}"))
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 验证 JSONPath 表达式
     */
    fun validatePath(jsonPath: String): Result<Boolean> {
        return try {
            JsonPath.compile(jsonPath)
            Result.success(true)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 批量查询
     */
    fun queryMultiple(json: String, jsonPaths: List<String>): Result<Map<String, String>> {
        return try {
            val results = mutableMapOf<String, String>()
            
            jsonPaths.forEach { path ->
                val result = query(json, path)
                results[path] = result.getOrElse { "Error: ${it.message}" }
            }
            
            Result.success(results)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 常用 JSONPath 示例
     */
    fun getExamples(): List<Pair<String, String>> {
        return listOf(
            "$.store.book[*].author" to "获取所有书籍的作者",
            "$.store.book[0]" to "获取第一本书",
            "$.store.book[-1]" to "获取最后一本书",
            "$.store.book[0,1]" to "获取前两本书",
            "$.store.book[:2]" to "获取前两本书（切片）",
            "$.store.book[?(@.price < 10)]" to "获取价格小于10的书",
            "$.store.book[?(@.price > 10 && @.category == 'fiction')]" to "价格大于10且分类为fiction",
            "$..*" to "获取所有元素",
            "$..book" to "获取所有book节点",
            "$.store.book[*].price" to "获取所有书籍的价格"
        )
    }
}

